import axios from 'axios'
import { getLocal, removeLocal } from '@/utils/Local.js'
import store from '@/store'
import router from '@/router'
import { Toast } from 'vant'
// 导入
import JSONbig from 'json-bigint'
// 可以通过axios的transformResponse方法，这个方法的作用是在传递给then/catch前，允许修改响应数据

// axios在这里默认把响应体从json字符串转成了js对象
axios.defaults.transformResponse = [
  function (data) {
    try {
      // 如果转换成功则返回转换的数据结果
      return JSONbig.parse(data)
    } catch (err) {
      // 如果转换失败，则包装为统一数据格式并返回
      return data
    }
  }
]

// 定义要取消的方法的集合
let cancelArr = []
/**
 * @description:定义取消某个接口的方法
 * @param {String} 要取消的接口url
 * @param {Boolean} 是否取消所有接口
 * @return:
 */
window.cancelAxios = function (url = '', cancelAll = false) {
  cancelArr = cancelArr.filter(item => {
    if (cancelAll) {
      // 如果取消所有接口请求
      item.c()
      // 取消的请求不再保存
      return false
    } else {
      if (item.url === url) {
        // 只取消指定url的接口
        item.c()
        return false
      } else {
        // 其他没匹配的接口的放回去asdasd
        return true
      }
    }
  })
}
// 全局配置
const _fetch = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn'
})
// 请求和响应拦截处理
_fetch.interceptors.request.use(
  config => {
    // 只给需要token的接口加token
    if (config.needToken) {
      config.headers.Authorization = `Bearer ${getLocal('token')}`
    }
    // 给每个上次调用的同一个接口取消请求
    if (config.url !== '/app/v1_1/articles') {
      window.cancelAxios(config.url)
    }
    // 给每个接口都加上一个遥控器
    config.cancelToken = new axios.CancelToken(cancel => {
      // 拿到接口的取消方法放入数组,加上接口的url唯一标识
      cancelArr.push({
        url: config.url,
        c: cancel
      })
    })
    return config
  },
  err => {
    return Promise.reject(err)
  }
)
_fetch.interceptors.response.use(
  response => {
    // 非200响应统一处理
    if (response.status === 200 || response.status === 201) return response.data
  },
  err => {
    const res = err.response
    // 401 token过期和无授权
    if (res.status === 401) {
      // 如果token过期,根据noError判断是否需要跳转登录页,true才不跳转
      // 过期的token直接删了
      removeLocal('token')
      // 错误提示
      Toast.fail('token已过期,请重新登录')
      // 修改登录状态
      store.commit('setIsLogin', false)
      // 跳转至登录页
      router.push('/login')
      // 阻止.then的执行
      return Promise.reject(new Error(res.data.message))
    } else {
      // 除了200,201,401之外的情况  其他自己处调用后处理
      // 不提示
      // Toast.fail(res.data.message)
      // 阻止.then执行
      // return Promise.reject(new Error(res.data.message))
      // 将错误反悔给自己根据情况处理
      return res
    }
  }
)
// 对axios二次封装
const _ajax = function (obj) {
  return new Promise((resolve, reject) => {
    _fetch(obj)
      .then(res => {
        resolve(res)
      })
      /* eslint-disable */
      .catch(err => {
        // console.log(err)
        // reject(err)
        // console.log(err.message)
      })
  })
}
// 将重新配置后的axios暴露出去
export default _ajax
